﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Caching;

namespace Trackr.Core.DataProvider
{
	public static class CacheUtility
	{
		/// <summary>
		/// Will get an object from the cache or use the delegate to load data and then insert it in the cache
		/// </summary>
		/// <typeparam name="T">The type of object to get</typeparam>
		/// <param name="cacheKey">The key to get the object for</param>
		/// <param name="loadDelegate">A delegate to load data</param>
		/// <returns></returns>
		public static T Get<T>(string cacheKey, Func<T> loadDelegate) where T : class
		{
			T obj = GetFromCache(cacheKey) as T;
			if (obj != null)
				return obj;
			if (loadDelegate != null)
			{
				obj = loadDelegate();
				AddToCache(cacheKey, obj);
			}
			return obj ?? default(T);
		}
		/// <summary>
		/// Will remove an object from the cache
		/// </summary>
		/// <param name="cacheKey"></param>
		public static void Remove(string cacheKey)
		{
			if (string.IsNullOrWhiteSpace(cacheKey))
				return;
			MemoryCache.Default.Remove(cacheKey);
		}
		/// <summary>
		/// Will clear the entire MemoryCache
		/// </summary>
		public static void Clear()
		{
			List<KeyValuePair<String, Object>> cacheItems = (from n in MemoryCache.Default.AsParallel() select n).ToList();
			foreach (KeyValuePair<String, Object> a in cacheItems)
			{
				MemoryCache.Default.Remove(a.Key);
			}
		}
		/// <summary>
		/// Returns an object from the cache
		/// </summary>
		/// <param name="cacheKey"></param>
		/// <returns></returns>
		private static object GetFromCache(string cacheKey) 
		{
			if (string.IsNullOrWhiteSpace(cacheKey))
				return null;
			return MemoryCache.Default.Get(cacheKey);
		}
		/// <summary>
		/// Adds an object to the cache
		/// </summary>
		/// <param name="cacheKey"></param>
		/// <param name="obj"></param>
		/// <param name="hours"></param>
		private static void AddToCache(string cacheKey, object obj, int hours = 8)
		{
			if (string.IsNullOrWhiteSpace(cacheKey) || obj == null)
				return;
			MemoryCache.Default.Add(cacheKey, obj, DateTimeOffset.Now.AddHours(hours));
		}
	}
}
